package info.cs52.bioinfo.hatien;

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

import prefuse.render.Renderer;
import prefuse.visual.VisualItem;

public class HatienNodeRenderer implements Renderer {

	private static final int RADIUS = 12;
	private static final int CELL_WIDTH = 24;
	private static final int CELL_HEIGHT = 14;
	private static final int BOX_HEIGHT = CELL_HEIGHT + 2;

	private int cellCount = 4;
	private int boxWidth;

	public HatienNodeRenderer(int cellCount) {
		super();
		this.cellCount = cellCount;
		boxWidth = (CELL_WIDTH + 1) * cellCount + 1;
	}

	private static final int SPACING = 5;

	@Override
	public void render(Graphics2D g, VisualItem item) {
		double size = item.getSize();
		int x = (int) item.getX();
		int y = (int) item.getY();

		FontMetrics fm = g.getFontMetrics();
		AffineTransform oldTransform = g.getTransform();
		g.transform(new AffineTransform(size, 0, 0, size,
				(1 - size) * item.getX(), (1 - size) * item.getY()));

		boolean active = item.getBoolean("active");
		g.setColor(active ? Color.red : Color.lightGray);
		g.fillOval(x - RADIUS, y - RADIUS, (int) RADIUS * 2, (int) RADIUS * 2);
		
		String label = item.getString("label");
		if (label != null) {
			g.setColor(Color.black);
			int stringX = x - fm.stringWidth(label)/2;
			int stringY = y + fm.getHeight()/2 - 2;
			g.drawString(label, stringX, stringY);
		}

		int boxX = x - boxWidth / 2;
		int boxY = y - (RADIUS + SPACING + BOX_HEIGHT);

		g.setColor(Color.white);
		g.fillRect(boxX, boxY, boxWidth, BOX_HEIGHT);

		g.setColor(Color.black);
		g.drawRect(boxX, boxY, boxWidth, BOX_HEIGHT);
		for (int i = 1; i < cellCount; i++) {
			int lineX = boxX + (CELL_WIDTH + 1) * i;
			g.drawLine(lineX, boxY, lineX, boxY + BOX_HEIGHT);
		}

		for (int i = 0; i < cellCount; i++) {
			int value = item.getInt("value" + i);
			String str = (value >= (Integer.MAX_VALUE/2) ? "∞" : String.valueOf(value));
			int stringX = boxX + (CELL_WIDTH + 1) * i + 1 + (CELL_WIDTH - fm.stringWidth(str)) / 2;
			int stringY = boxY + CELL_HEIGHT - 1 - (CELL_HEIGHT - fm.getHeight()) / 2;
			g.drawString(str, stringX, stringY);
		}

		g.setTransform(oldTransform);
	}

	@Override
	public boolean locatePoint(Point2D p, VisualItem item) {
		return p.distance(new Point2D.Double(item.getX(), item.getY())) <= RADIUS;
	}

	@Override
	public void setBounds(VisualItem item) {
		double x = item.getX() - boxWidth / 2;
		double y = item.getY() - RADIUS - SPACING - BOX_HEIGHT;
		double w = boxWidth;
		double h = 2 * (RADIUS + SPACING + BOX_HEIGHT);
		item.setBounds(x, y, w, h);
	}

}
